package crm8000.services

import crm8000.Models.Goods;
import crm8000.Models.Invertory;
import crm8000.Models.InvertoryDetail
import crm8000.Models.PWBill;
import crm8000.Models.PWBillDetail;
import crm8000.Models.Payables;
import crm8000.Models.PayablesDetail;
import crm8000.Models.Supplier;
import crm8000.Models.User;
import crm8000.Models.Warehouse;
import crm8000.helper.Result
import crm8000.viewModels.PwBillVM;
import grails.transaction.Transactional

/**
 * 采购入库单Service
 *
 */
@Transactional
class PwBillService {

	UserService userService

	def pwbillList() {
		def data = PWBill.findAllByBillStatus(0);
		def result = []

		for (item in data) {
			def pw = new PwBillVM(id: item.id, ref: item.ref,
			bizDate: item.bizDT.format("yyyy-MM-dd"),
			supplierName: item.supplier.name,
			warehouseName: item.warehouse.name,
			billStatus: "待提交",
			inputUserName: item.inputUser.name,
			bizUserName: item.bizUser.name)

			pw.amount = PWBillDetail.createCriteria().get {
				projections { sum("goodsMoney") }
				pwBill { eq "id", item.id }
			}

			result.add(pw)
		}
		return result
	}

	Result editPWBill(params) {
		if (params.id) {
			// 编辑
			def user = User.get(params.bizUserId)
			if (!user) {
				return new Result(success: false, msg: "业务人员不存在")
			}
			def warehouse = Warehouse.get(params.warehouseId)
			if (!warehouse) {
				return new Result(success: false, msg: "仓库不存在")
			}
			def supplier = Supplier.get(params.supplierId)
			if (!supplier) {
				return new Result(success: false, msg: "供应商不存在")
			}

			def pwBill = PWBill.get(params.id)
			if (!pwBill) {
				return new Result(success: false, msg: "要编辑的采购入库单主记录不存在")
			}

			if (pwBill.billStatus != 0) {
				return new Result(success: false, msg: "采购入库单已经提交，不能再编辑")
			}

			pwBill.supplier = supplier
			pwBill.warehouse = warehouse
			pwBill.bizUser = user
			pwBill.inputUser = userService.loginUser
			pwBill.bizDT = Date.parse("yyyy-MM-dd", params.bizDT)

			pwBill.save()

			return new Result(success: true, id: pwBill.id)
		} else {
			// 新建
			def user = User.get(params.bizUserId)
			if (!user) {
				return new Result(success: false, msg: "业务人员不存在")
			}
			def warehouse = Warehouse.get(params.warehouseId)
			if (!warehouse) {
				return new Result(success: false, msg: "仓库不存在")
			}
			def supplier = Supplier.get(params.supplierId)
			if (!supplier) {
				return new Result(success: false, msg: "供应商不存在")
			}

			def pwBill = new PWBill()
			pwBill.ref = this.genNewBillRef();
			pwBill.supplier = supplier
			pwBill.warehouse = warehouse
			pwBill.bizUser = user
			pwBill.inputUser = userService.loginUser
			pwBill.bizDT = Date.parse("yyyy-MM-dd", params.bizDT)
			pwBill.billStatus = 0
			pwBill.goodsMoney = 0
			pwBill.save()

			return new Result(success: true, id: pwBill.id)
		}
	}

	Result deletePWBill(String id) {
		def pwBill = PWBill.get(id)
		if (!pwBill) {
			return new Result(success: false, msg: "要删除的采购入库单不存在")
		}

		if (pwBill.billStatus != 0) {
			return new Result(success: false, msg: "采购入库单已经提交，不能删除")
		}

		pwBill.delete()

		return new Result(success: true)
	}

	Result editPWBillDetail(params) {
		def bill = PWBill.get(params.pwBillId)
		if (!bill) {
			return new Result(success: false, msg: "采购入库单主记录不存在")
		}

		if (bill.billStatus != 0) {
			return new Result(success: false, msg: "采购入库单已经提交，不能再新建商品明细记录")
		}

		def goods = Goods.get(params.goodsId)
		if (!goods) {
			return new Result(success: false, msg: "商品不存在")
		}

		def goodsPrice = params.goodsPrice.toBigDecimal()
		def goodsCount = params.goodsCount.toInteger()
		def goodsMoney = goodsCount * goodsPrice
		
		if (params.id) {
			// 编辑
			def pwd = PWBillDetail.get(params.id)
			if (!pwd) {
				return new Result(success: false, msg: "要编辑的商品明细记录不存在")
			}
			pwd.goods = goods
			pwd.goodsPrice = goodsPrice
			pwd.goodsCount = goodsCount
			pwd.goodsMoney = goodsMoney

			pwd.save()
			
			return new Result(success: true, id: pwd.id)
		} else {
			// 新增
			def pwd = new PWBillDetail()
			pwd.pwBill = bill
			pwd.goods = goods
			pwd.goodsPrice = goodsPrice
			pwd.goodsCount = goodsCount
			pwd.goodsMoney = goodsMoney
			def showOrder = PWBillDetail.createCriteria().get {
				projections { max("showOrder") }
				pwBill { eq "id", bill.id }
			}
			if (!showOrder) {
				showOrder = 0
			}
			pwd.showOrder = showOrder + 1
			pwd.save()

			return new Result(success: true, id: pwd.id)
		}
	}

	def pwBillDetailList(String pwBillId) {
		return PWBillDetail.createCriteria().list {
			pwBill { eq "id", pwBillId}
			order "showOrder"
		}
	}

	/**
	 * 生成采购入库单的新单号
	 * @return 新单号
	 */
	String genNewBillRef() {
		def pre = "PW"
		def mid = new Date().format("yyyyMMdd")
		def pwBill = PWBill.createCriteria().get {
			ilike "ref", pre + mid + "%"
			order "ref", "desc"
			maxResults 1
		}
		if (!pwBill) {
			return pre + mid + "001"
		} else {
			def suf = (pwBill.ref.substring(10).toInteger() + 1).toString()
			def str = ""
			for (int i = 0; i < 3 - suf.length(); i++) {
				str += "0"
			}
			suf = str + suf

			return pre + mid + suf
		}
	}

	def pwBillInfo(String id) {
		return PWBill.get(id)
	}

	/**
	 * 提交采购入库单
	 * @param id
	 * @return
	 */
	Result commitPWBill(String id) {
		def bill = PWBill.get(id)
		if (!bill) {
			return new Result(success: false, msg: "要提交的采购入库单不存在")
		}

		if (bill.billStatus != 0) {
			return new Result(success: false, msg: "当前采购入库单已经提交过，不能再次提交")
		}

		if (!bill.warehouse.inited) {
			return new Result(success: false, msg: "仓库 [<span style='color:red'>${bill.warehouse.name}</span>] 还没有完成建账，不能对其做入库操作")
		}

		if (bill.details.size() == 0) {
			return new Result(success: false, msg: "当前采购入库单没有录入商品明细，不能提交")
		}
		
		// 检查入库数量和单价不能为负数
		for (detail in bill.details) {
			if (detail.goodsCount <= 0) {
				return new Result(success: false, msg: "商品 [${detail.goods.name}] 的采购数量需要大于0")
			}
			
			if (detail.goodsPrice <= 0) {
				return new Result(success: false, msg: "商品 [${detail.goods.name}] 的采购单价需要大于0")
			}
		}

		for (detail in bill.details) {
			def g = detail.goods

			// 记库存总账
			def inv = Invertory.findByGoodsAndWarehouse(g, bill.warehouse)
			if (!inv) {
				inv = new Invertory()
				inv.warehouse = bill.warehouse
				inv.goods = g
				inv.inCount = detail.goodsCount
				inv.inPrice = detail.goodsPrice
				inv.inMoney = detail.goodsMoney
				inv.balanceCount = detail.goodsCount
				inv.balancePrice = detail.goodsPrice
				inv.balanceMoney = detail.goodsMoney

				inv.save()
			} else {
				inv.inCount += detail.goodsCount
				inv.inMoney += detail.goodsMoney
				inv.inPrice = inv.inMoney / inv.inCount
				inv.balanceCount += detail.goodsCount
				inv.balanceMoney += detail.goodsMoney
				inv.balancePrice = inv.balanceMoney / inv.balanceCount
				inv.save()
			}

			// 记库存明细账
			def invDetail = new InvertoryDetail()
			invDetail.warehouse = bill.warehouse
			invDetail.goods = g
			invDetail.inCount = detail.goodsCount
			invDetail.inPrice = detail.goodsPrice
			invDetail.inMoney = detail.goodsMoney
			invDetail.balanceCount = inv.balanceCount
			invDetail.balancePrice = inv.balancePrice
			invDetail.balanceMoney = inv.balanceMoney

			invDetail.refNumber = bill.ref
			invDetail.refType = "采购入库"

			invDetail.bizDate = bill.bizDT
			invDetail.bizUser = bill.bizUser

			invDetail.save()
		}

		bill.billStatus = 1

		bill.goodsMoney = PWBillDetail.createCriteria().get {
			projections { sum("goodsMoney") }
			pwBill { eq "id", bill.id }
		}
		
		bill.save()
		
		// 记应付账款，按供应商汇总
		def pay = Payables.findByCaIdAndCaType(bill.supplier.id, "supplier")
		if (!pay) {
			pay = new Payables(caId: bill.supplier.id, caType: "supplier", 
				payMoney: bill.goodsMoney, actMoney: 0, balanceMoney: bill.goodsMoney)
			pay.save()	
		} else {
			pay.payMoney += bill.goodsMoney
			pay.balanceMoney += bill.goodsMoney
			
			pay.save()
		}
		
		//记应付账款，按单据汇总
		def payDetail = new PayablesDetail()
		payDetail.caId = bill.supplier.id
		payDetail.caType = "supplier"
		payDetail.refType = "采购入库"
		payDetail.refNumber = bill.ref
		payDetail.payMoney = bill.goodsMoney
		payDetail.actMoney = 0
		payDetail.balanceMoney = bill.goodsMoney
		payDetail.save()

		return new Result(success: true)
	}

	def refreshPWBillInfo(String id) {
		return PWBillDetail.createCriteria().get {
			projections { sum("goodsMoney") }
			pwBill { eq "id", id }
		}
	}

	def pwBillDetailInfo(String id) {
		return PWBillDetail.get(id)
	}
	
	Result deletePWBillDetail(String id) {
		def pwd = PWBillDetail.get(id)
		if (!pwd) {
			return new Result(success: false, msg: "要删除的商品明细不存在")
		}
		
		if (pwd.pwBill.billStatus != 0) {
			return new Result(success: false, msg: "当前采购入库单已经提交，不能再删除商品明细记录")
		}
		
		pwd.delete()
		
		return new Result(success: true)
	}
}